﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using SW.Lite.IDAL.Master;
using SW.Lite.Infrastructure.Common;
using SW.Lite.Infrastructure.Helpers;
using SW.Lite.Model.Master;

namespace SW.Lite.DAL.MsSql.Master
{
    public class Admin : IAdmin
    {
        public bool Exists(int id)
        {
            const string sql = "SELECT COUNT(1) FROM SW_M_Admin WHERE Id =@Id";
            var paramter = new SqlParameter("@Id", SqlDbType.Int) { Value = id };
            return MsSqlHelper.Exists(sql, paramter);
        }

        public AdminModel Single(int id)
        {
            const string sql =
                "SELECT Id, UserName, NickName, Password, PasswordSalt, Face, LoginCount, LastLoginTime, LastLoginIP FROM SW_M_Admin WHERE Id = Id";

            var paramter = new SqlParameter("@Id", SqlDbType.Int) { Value = id };
            return FillSingle(sql, paramter);
        }

        public AdminModel Single(string userName)
        {
            const string sql =
                "SELECT Id, UserName, NickName, Password, PasswordSalt, Face, LoginCount, LastLoginTime, LastLoginIP FROM SW_M_Admin WHERE UserName = @UserName";

            var paramter = new SqlParameter("@UserName", SqlDbType.NVarChar) { Value = userName };
            return FillSingle(sql, paramter);
        }

        public PageList<AdminModel> All()
        {
            const string sql =
                "SELECT Id, UserName, NickName, Password, PasswordSalt, Face, LoginCount, LastLoginTime, LastLoginIP FROM SW_M_Admin";

            return FillList(sql);
        }

        public PageList<AdminModel> All(int pageIndex, int pageSize)
        {
            var start = (pageIndex - 1) * pageSize;
            var end = pageIndex * pageSize;

            var sql = string.Format(@"SELECT Id, UserName, NickName, Password, PasswordSalt, Face, LoginCount, LastLoginTime, LastLoginIP FROM (SELECT ROW_NUMBER() OVER (ORDER BY Id) ROWNO,* FROM SW_M_Admin) A WHERE A.ROWNO BETWEEN {0} AND {1};
SELECT COUNT(1) FROM SW_M_Admin;", start, end);

            return FillList(sql);
        }

        public ExecuteResult Insert(AdminModel model)
        {
            const string sql =
                "INSERT INTO SW_M_Admin (UserName, NickName, Password, PasswordSalt, Face, LoginCount, LastLoginTime, LastLoginIP) VALUES(UserName, @NickName, @Password, @PasswordSalt, @Face, @LoginCount, @LastLoginTime, @LastLoginIP)";

            var parameters = new[]
            {
                new SqlParameter("@UserName", SqlDbType.NVarChar) {Value = model.UserName},
                new SqlParameter("@NickName", SqlDbType.NVarChar) {Value = model.NickName},
                new SqlParameter("@Password", SqlDbType.NVarChar) {Value = model.Password},
                new SqlParameter("@PasswordSalt", SqlDbType.NVarChar) {Value = model.PasswordSalt},
                new SqlParameter("@Face", SqlDbType.NVarChar) {Value = model.Face},
                new SqlParameter("@LoginCount", SqlDbType.Int) {Value = model.LoginCount},
                new SqlParameter("@LastLoginTime", SqlDbType.DateTime) {Value = model.LastLoginTime},
                new SqlParameter("@LastLoginIP", SqlDbType.NVarChar) {Value = model.LastLoginIP}
            };

            var result = MsSqlHelper.Execute(sql, parameters);
            return 0 == result ? new ExecuteResult(false) : new ExecuteResult(true);
        }

        public ExecuteResult Update(AdminModel model)
        {
            const string sql =
                "UPDATE SW_M_Admin SET UserName = @UserName, NickName = @NickName, Password = @Password, PasswordSalt = @PasswordSalt, Face = @Face, LoginCount = @LoginCount, LastLoginTime = @LastLoginTime, LastLoginIP = @LastLoginIP WHERE Id = @Id ";
            var parameters = new[]
            {
                new SqlParameter("@Id", SqlDbType.Int) {Value = model.Id},
                new SqlParameter("@UserName", SqlDbType.NVarChar) {Value = model.UserName},
                new SqlParameter("@NickName", SqlDbType.NVarChar) {Value = model.NickName},
                new SqlParameter("@Password", SqlDbType.NVarChar) {Value = model.Password},
                new SqlParameter("@PasswordSalt", SqlDbType.NVarChar) {Value = model.PasswordSalt},
                new SqlParameter("@Face", SqlDbType.NVarChar) {Value = model.Face},
                new SqlParameter("@LoginCount", SqlDbType.Int) {Value = model.LoginCount},
                new SqlParameter("@LastLoginTime", SqlDbType.DateTime) {Value = model.LastLoginTime},
                new SqlParameter("@LastLoginIP", SqlDbType.NVarChar) {Value = model.LastLoginIP}
            };

            var result = MsSqlHelper.Execute(sql, parameters);
            return 0 == result ? new ExecuteResult(false) : new ExecuteResult(true);
        }

        public ExecuteResult Delete(params int[] ids)
        {
            if (ids == null || ids.Length <= 0)
                return new ExecuteResult { Result = false, Message = "删除失败" };

            var sql = "DELETE FROM SW_M_Admin WHERE Id IN(" + String.Join(",", ids.Select(id => id.ToString())) + ")";
            var result = MsSqlHelper.Execute(sql);
            return 0 == result ? new ExecuteResult(false) : new ExecuteResult(true);
        }

        public ExecuteResult AddAdminRoles(int adminId, bool deleteAllBeforeAdd, params int[] roleIds)
        {
            if (roleIds == null || roleIds.Length <= 0)
                return new ExecuteResult { Result = false, Message = "添加失败" };

            if (deleteAllBeforeAdd)
            {
                var sql = "DELETE FROM SW_M_AdminRole WHERE AdminID=" + adminId;

                var deleteResult = MsSqlHelper.Execute(sql);
                if (deleteResult <= 0)
                    return new ExecuteResult { Result = false, Message = "删除已存在记录失败" };
            }

            var sb = new StringBuilder();
            foreach (var roleId in roleIds)
                sb.AppendLine(String.Format("INSERT INTO SW_M_AdminRole(AdminID,RoleID)VALUES({0},{1})", adminId, roleId));

            var result = MsSqlHelper.Execute(sb.ToString());
            return 0 == result ? new ExecuteResult(false) : new ExecuteResult(true);
        }

        private AdminModel FillSingle(string sql, params SqlParameter[] paramters)
        {
            AdminModel data = null;
            using (var rdr = MsSqlHelper.ExecuteReader(sql, paramters))
            {
                if (rdr.Read())
                    data = ReadData(rdr);
            }
            return data;
        }

        private PageList<AdminModel> FillList(string sql, params SqlParameter[] paramters)
        {
            var list = new PageList<AdminModel>();
            using (var rdr = MsSqlHelper.ExecuteReader(sql, paramters))
            {
                while (rdr.Read())
                    list.Add(ReadData(rdr));
                if (rdr.NextResult() && rdr.Read())
                    list.AllCount = rdr.GetInt32(0);
                else
                    list.AllCount = list.Count;
            }
            return list;
        }

        private AdminModel ReadData(SqlDataReader dr)
        {
            return new AdminModel
            {
                Id = Convert.ToInt32(dr["Id"]),
                UserName = Convert.ToString(dr["UserName"]),
                NickName = Convert.ToString(dr["NickName"]),
                Password = Convert.ToString(dr["Password"]),
                PasswordSalt = Convert.ToString(dr["PasswordSalt"]),
                Face = Convert.ToString(dr["Face"]),
                LoginCount = Convert.ToInt32(dr["LoginCount"]),
                LastLoginTime = Convert.ToDateTime(dr["LastLoginTime"]),
                LastLoginIP = Convert.ToString(dr["LastLoginIP"])
            };
        }
    }
}